/**
 * Copyright (C) 2021 All rights reserved.
 *
 * @file main.h
 * @author Wang Haibin
 * @email wanghaibin@qiyi.com
 * @date Thu Jul 21 11:20:09 CST 2022
 * @brief

*/

// #include <stdlib.h>
// #include <stdio.h>
// #include <string.h>
// #include <unistd.h>
// #include <sys/mman.h>
// #include <malloc.h>
//
// size_t  heap_malloc_total, heap_free_total,mmap_total, mmap_count;
//
// void print_info()
// {
//     struct mallinfo mi = mallinfo();
//     printf("自己的统计:\n");
//     printf("\theap_malloc_total=%lu heap_free_total=%lu heap_in_use=%lu\n\tmmap_total=%lu mmap_count=%lu\n",
//             heap_malloc_total*1024, heap_free_total*1024, heap_malloc_total*1024-heap_free_total*1024,
//             mmap_total*1024, mmap_count);
//     printf("mallinfo 统计:\n");
//     printf("\theap_malloc_total=%lu heap_free_total=%lu heap_in_use=%lu\n\tmmap_total=%lu mmap_count=%lu\n",
//             mi.arena, mi.fordblks, mi.uordblks,
//             mi.hblkhd, mi.hblks);
//     printf("from malloc_stats:\n");
//     malloc_stats();
// }
//
// #define ARRAY_SIZE 200
// int main(int argc, char** argv)
// {
//     char* ptr_arr[ARRAY_SIZE];
//     int i;
//     for( i = 0; i < ARRAY_SIZE; i++)
//     {
//         ptr_arr[i] = (char*)malloc(i * 1024);
//         if ( i < 128)                                      //glibc默认128k以上使用mmap
//         {
//             heap_malloc_total += i;
//         }
//         else
//         {
//             mmap_total += i;
//             mmap_count++;
//         }
//     }
//     print_info();
//
//     for( i = 0; i < ARRAY_SIZE; i++)
//     {
//         if ( i % 2 == 0)
//             continue;
//         free(ptr_arr[i]);
//
//         if ( i < 128)
//         {
//             heap_free_total += i;
//         }
//         else
//         {
//             mmap_total -= i;
//             mmap_count--;
//         }
//     }
//     printf("\nafter free\n");
//     print_info();
//
//     return 1;
// }




#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <iostream>
#include <fstream>
#include <errno.h>
#include <cstdio>
#include <cstdlib>

// 获取当前进程的内存使用情况
void get_memory_usage(size_t &rss_kb, size_t &total_mem_kb) {
    std::ifstream statm_file("/proc/self/statm");
    if (!statm_file.is_open()) {
        std::cerr << "Failed to open /proc/self/statm" << std::endl;
        return;
    }
    size_t size=0, resident=0, share=0, text=0, lib=0, data=0, dt=0;
    statm_file >> size >> resident >> share >> text >> lib >> data >> dt;
    statm_file.close();
    rss_kb = resident * getpagesize()/1024;
    total_mem_kb = size * getpagesize()/1024;
}

void trim_memory_if_needed() {
    size_t rss_before, total_mem_before;
    get_memory_usage(rss_before, total_mem_before);

	std::cout << "page size=" << getpagesize() << std::endl;
    std::cout << "RSS before trim: " << rss_before  << " KB" << std::endl;
    std::cout << "Total memory before trim: " << total_mem_before  << " KB" << std::endl;

    // 计算空闲内存率
    double free_mem_ratio = (double)(total_mem_before - rss_before) / total_mem_before;

    // 如果空闲内存率超过一定阈值（例如 25%），则调用 malloc_trim(0)
    if (free_mem_ratio > 0.25) {
        std::cout << "Calling malloc_trim(0) to release unused memory." << std::endl;
        if (malloc_trim(0) == 0) {
            std::cerr << "malloc_trim() failed: " << strerror(errno) << std::endl;
        }

        size_t rss_after, total_mem_after;
        get_memory_usage(rss_after, total_mem_after);

        std::cout << "RSS after trim: " << rss_after / 1024 << " KB" << std::endl;
        std::cout << "Total memory after trim: " << total_mem_after / 1024 << " KB" << std::endl;
    } else {
        std::cout << "No need to trim memory." << std::endl;
    }
}

int main() {

    // 模拟内存分配
    const size_t alloc_size = 100 * 1024 * 1024;  // 100 MB
    char* buffer = (char*)malloc(alloc_size);
    if (buffer) {
        memset(buffer, 1, alloc_size); // 使用分配的内存以便实际分配
    }

    // 观察是否需要进行内存整理
    trim_memory_if_needed();

    // 释放分配的内存
    free(buffer);

    size_t rss_before, total_mem_before;
    get_memory_usage(rss_before, total_mem_before);
	printf("rss=%lu, t=%lu\n", rss_before, total_mem_before);
	sleep(100);
    return 0;
}

